/*
 * IJA2011, Board game "Clovece nezlob se"
 * grp108
 * Tomáš Mičiak,xmicia00
 * Andrej Martinák, xmarti51
 *
 */


package src.clovece.game;


import java.net.*;
import java.io.*;
import java.util.*;
import java.io.FileInputStream;


/**
 *
 * @author amk
 */
public class Server implements Runnable{

      private Socket connection;
      private String TimeStamp;
      private int ID;
      private ServerData data = ServerData.getServerDataInstance();
      private boolean LOGIN = false;

      public static void main(String[] args) {
      int port = 19999;
      int count = 0;
        try{
          ServerSocket socket1 = new ServerSocket(port);
          System.out.println("Server Initialized");
          while (true) {
            Socket connection = socket1.accept();
            Runnable runnable = new Server(connection, ++count);
            Thread thread = new Thread(runnable);
            thread.start();
          }
        }
        catch (Exception e) {}
      }

    Server(Socket s, int i) {
      this.connection = s;
      this.ID = i;
      this.data.addConnection(s);
}

public void run() {
    try {
      BufferedInputStream is = new BufferedInputStream(connection.getInputStream());
      InputStreamReader isr = new InputStreamReader(is);
      int character;
      StringBuffer process = new StringBuffer();
      
      while((character = isr.read()) != 13) {
        process.append((char)character);
      }
      System.out.println(process);
      try {
          process.append((char)30);
          String message = process.toString();
          String stage = new String();
          char[] chars = message.toCharArray();

          int i = 0;
          while (chars[i] != ':')
          {
              stage += chars[i];
              i++;
          }

          if (stage.equals("Register"))
          {
               String username = new String();
               String password = new String();
               i++;
               while (chars[i] != '|')
               {
                  username += chars[i];
                  i++;
               }

               i++;
               while (chars[i] != 30)
               {

                  password += chars[i];
                  i++;
               }

               Properties db = new Properties();
               db.load(new FileInputStream(System.getProperty("user.dir") + System.getProperty("file.separator") + "lib" +
               System.getProperty("file.separator")  + "database.db"));

               db.put(username.toString(), password.toString());

               try {
                    db.store(new FileOutputStream(System.getProperty("user.dir") + System.getProperty("file.separator") + "lib" +
               System.getProperty("file.separator")  + "database.db"), null);

                }
                catch (IOException e) {
                }
               System.out.println(this.LOGIN);

          }
          else if (stage.equals("Login"))
          {
                this.LOGIN = true;

               String username = new String();
               String password = new String();
               i++;
               while (chars[i] != '|')
               {
                  username += chars[i];
                  i++;
               }
               data.setPlayerName(username);
               i++;
               while (chars[i] != 30)
               {

                  password += chars[i];
                  i++;
               }

               Properties db = new Properties();
               db.load(new FileInputStream(System.getProperty("user.dir") + System.getProperty("file.separator") + "lib" +
               System.getProperty("file.separator")  + "database.db"));

               String loadedUsername = new String();
               String loadedPassword = new String();
               String answer = new String();

               loadedPassword = db.getProperty(username);


               if (loadedPassword != null)
               {
                   if (loadedPassword.equals(password)){
                       answer = "OK:" + (char) 13;  //Login prebehol v poriadku
                       data.setNextPlayerName(loadedUsername);
                   }
                   else answer = "Error:password" + (char) 13;   //User je OK, ale heslo je zle

               }
               else answer = "Error:user"+ (char) 13; //Zadany User neexistuje!

             BufferedOutputStream os = new BufferedOutputStream(connection.getOutputStream());
             OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
             osw.write(answer);
             osw.flush();
            }

            else if (stage.equals("skuska"))
            {
                String answer = "Je pripojenych " + (this.data.getIndex()) + " klientov" + (char) 13;
                //this.data.getOutputStream(0).write(answer);
                //this.data.getOutputStream(0).flush();
                
                this.data.getOutputStream(1).write(answer);
                this.data.getOutputStream(1).flush();

                //this.data.getOutputStream(0).write("END"+ (char) 13);
                //this.data.getOutputStream(0).flush();

                //this.data.getOutputStream(1).write("END"+ (char) 13);
                //this.data.getOutputStream(1).flush();
             }

             if (this.LOGIN == true)
             {
               System.out.println(this.LOGIN);
               String msg = null;
               try {
                        //System.out.println("Reading");
                        BufferedReader rd = new BufferedReader(new InputStreamReader(this.connection.getInputStream()));

                          String str;
                          while (true) {
                            str = rd.readLine();

                            if (str != null)
                                msg = str ;
                            if (str.equals("NewGame:"))
                             {
                                data.setNewgame(true);
                                str = rd.readLine();
                                data.setNumberOfPlayers(Integer.parseInt(str));
                                str = rd.readLine();
                                data.setGameBoardSize(Integer.parseInt(str));
                                break;
                              }
                            if (str.equals("JustLogin:"))
                             break;

                            str = null;
                           }
                     }
                    catch (IOException f) {
                      System.out.println("IOException: " + f);
                    }
                      catch (Exception g) {
                      System.out.println("Exception: " + g);
                    }
 
                System.out.println("msg je: " + msg);
                System.out.println("Pocet hracov: " + data.getNumberOfPlayers());
                System.out.println("Velkost pola: " + data.getGameBoardSize());
              

              if (data.getNewgame() == true)
              {
                //while (true){

                        if (this.data.getIndex() == data.getNumberOfPlayers())
                        {
                            this.data.getOutputStream(0).write("PlayersJoined"+ (char) 13);
                            this.data.getOutputStream(0).flush();
                            //this.data.getOutputStream(0).write("END"+ (char) 13);
                            //this.data.getOutputStream(0).flush();

                            for (int x = 1; x < data.getNumberOfPlayers(); x++)
                            {
                                this.data.getOutputStream(x).write(String.valueOf(data.getNumberOfPlayers())+ (char) 13);
                                this.data.getOutputStream(x).flush();
                                //this.data.getOutputStream(x).write("END"+ (char) 13);
                                //this.data.getOutputStream(x).flush();
                            }

                            for (int x = 1; x < data.getNumberOfPlayers(); x++)
                            {
                                this.data.getOutputStream(x).write(String.valueOf(data.getGameBoardSize())+ (char) 13);
                                this.data.getOutputStream(x).flush();
                                //this.data.getOutputStream(x).write("END"+ (char) 13);
                                //this.data.getOutputStream(x).flush();
                            }

                            for (int x = 1; x < data.getNumberOfPlayers(); x++)
                            {
                                this.data.getOutputStream(x).write(String.valueOf(data.getNumberOfPlayers())+ (char) 13);
                                this.data.getOutputStream(x).flush();
                                //this.data.getOutputStream(x).write("END"+ (char) 13);
                                //this.data.getOutputStream(x).flush();
                            }

                            for (int x = 0; x < data.getNumberOfPlayers(); x++)
                            {
                                for (int y = 0; y < data.getNumberOfPlayers(); y++)
                                {
                                    this.data.getOutputStream(y).write(data.getPlayerName(x)+ (char) 13);
                                    this.data.getOutputStream(y).flush();
                                    //this.data.getOutputStream(y).write("END"+ (char) 13);
                                    //this.data.getOutputStream(y).flush();
                                }
                            }

                            int[] randomValues = new int[6];
                            Random generator = new Random();
                            int randomValue;
                            for(int y = 0; y < 6; y++) {
                                randomValues[y] = -1;
                            }
                            for(int y = 0; y < 6; y++) {
                                randomValue = generator.nextInt(6);
                                for(int j = 0; j <= y; j++) {
                                    if(randomValue == randomValues[j]) {
                                        randomValue = generator.nextInt(6);
                                        j = -1;
                                    }
                                    if(j == y) {
                                        randomValues[j] = randomValue;
                                    }
                                }
                            }
                            for(int y = 0; y < data.getNumberOfPlayers(); y++) {
                                for (int x = 0; x < 6; x++)
                                {
                                    this.data.getOutputStream(y).write(String.valueOf(randomValues[x])+ (char) 13);
                                    this.data.getOutputStream(y).flush();
                                    //this.data.getOutputStream(y).write("END"+ (char) 13);
                                    //this.data.getOutputStream(y).flush();
                                }
                            }

                        }
                //} 
                        String move = null;
                        String str;
                        BufferedReader rd = new BufferedReader(new InputStreamReader(this.connection.getInputStream()));

                        while(true)
                        {
                            move = null;
                            // citanie spravy
                            try {
                                str = rd.readLine();
                                if (str != null)
                                   move = str;

                            }
                            catch (IOException f) {
                              System.out.println("IOException: " + f);
                            }
                              catch (Exception g) {
                              System.out.println("Exception: " + g);
                            }

                            // posielanie vsetkym
                            for (int z = 0; z < data.getNumberOfPlayers(); z++)
                            {
                                if (data.getSocketIndex(this.connection) != z)
                                {
                                    this.data.getOutputStream(z).write(move + (char) 13);
                                    System.out.println(move);
                                    this.data.getOutputStream(z).flush();
                                }
                            }
                        }

              }
              else {
                  this.data.getOutputStream(0).write("NoGame"+ (char) 13);
                  this.data.getOutputStream(0).flush();
//                  this.data.getOutputStream(0).write("END"+ (char) 13);
//                  this.data.getOutputStream(0).flush();
                  this.LOGIN = false;
              }
          }

      }
      catch (Exception e){}
    }
    catch (Exception e) {
      System.out.println(e);
    }
    finally {
      try {
        if ((LOGIN == false) || (data.getNewgame() == false && LOGIN == false))
        {
          connection.close();
          this.data.userDisconnected();
        }
     }
      catch (IOException e){}
    }
}
}







